package com.globant.google.mendoza.malbec;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * Utility class for base64 encoding and signing.
 */
public final class Encoder {

  /** The signing algorithm.
   */
  private static final String SIGNING_ALGORITHM = "HmacSHA1";

  /**
   * The private constructor.
   */
  private Encoder() {
    // nothing to do.
  }

  /** Signs the shopping cart using HMAC_SHA1.
  *
  * @todo The cart is converted twice to xml: one when signing and another
  * when encoding. Given that the cart is inmutable, we could cache the result
  * of the xml conversion.
  *
  * @param source The source to be signed.
  *
  * @param key The key to use to sign the xml. It cannot be null.
  *
  * @return The base64 encoded signature of the xml representation of this
  * cart.
  */
 public static String sign(final String source, final String key) {
   if (key == null) {
     throw new IllegalArgumentException("key cannot be null");
   }
   Mac mac = null;

   try {
     mac = Mac.getInstance(SIGNING_ALGORITHM);
     mac.init(new SecretKeySpec(key.getBytes(), SIGNING_ALGORITHM));
   } catch (NoSuchAlgorithmException e) {
     throw new RuntimeException(e);
   } catch (InvalidKeyException e) {
     throw new RuntimeException(e);
   }

   final byte[] result = mac.doFinal(source.getBytes());
   final String signature = new String(Base64.encodeBase64(result));

   return signature;
 }

 /** Base64 encodes the xml representation of this cart.
  *
  * @param source The source to be encoded.
  *
  * @return Returns a string with the encoded xml cart.
  */
 public static String encode(final String source) {
   final String encoded = new String(Base64.encodeBase64(source.getBytes()));
   return encoded;
 }
}
